desc:Elan Chaos Generator 1.1

/* 
by Elan Hickler 
www.elanhickler.com 
www.soundemote.com
*/

slider1:0<0,6,1{stereo chaos (pre-filter),stereo chaos,chaos A (pre-filter),chaos A,chaos B,mono mix(pre-filter),mono mix}>output
slider2:0<-10000,10000,1>Master Frequency
slider3:0<-20000,20000,.001>Master FM

slider5:1<0,1,.0001>Lowpass Chaos (1=off)
slider6:4<0,4,1{1,2,4,8,16}>^ filter taps
slider7:1<0,1,.0001>Highpass Chaos (1=off)
slider8:0<-.2,.2,.00001>^ finetune

slider13:0<-100,100,.0001>osc1 detune
slider14:0<-100,100,.0001>osc2 detune
slider15:0<-20000,20000,.001>fm1 offset
slider16:0<-20000,20000,.001>fm2 offset

slider20:.5<0,1,.001>Volume
slider21:.5<0,1,.001>Pan

@init
function clamp(value,lo,hi) local(lo hi)
(
  value = value > hi ? hi : value;
  value = value < lo ? lo : value;
);

pi=$pi;
twopi = 2*$pi;
coefficient = .999;

@slider
mix  = slider1;
taps = slider6;
pan  = slider21;

@sample
frequency = slider2*twopi/srate;
fm1       = slider15+slider3;
fm2       = slider16+slider3;
lpcut     = 1-slider5;
hpcut     = min(1,slider7+slider8);
volume    = slider20;
osc1f     = slider13*twopi/srate;
osc2f     = slider14*twopi/srate;
fmoff     = slider3;
speed     = slider16;

i=100;
i+=1; fm1       = buf[i] = (fm1 * (1-coefficient)) + (buf[i] * coefficient);
i+=1; fm2       = buf[i] = (fm2 * (1-coefficient)) + (buf[i] * coefficient);
i+=1; lpcut     = buf[i] = (lpcut * (1-coefficient)) + (buf[i] * coefficient);
i+=1; hpcut     = buf[i] = (hpcut * (1-coefficient)) + (buf[i] * coefficient);
i+=1; frequency = buf[i] = (frequency * (1-coefficient)) + (buf[i] * coefficient);
i+=1; volume    = buf[i] = (volume  * (1-coefficient)) + (buf[i] * coefficient);
i+=1; osc1f     = buf[i] = (osc1f  * (1-coefficient)) + (buf[i] * coefficient);
i+=1; osc2f     = buf[i] = (osc2f  * (1-coefficient)) + (buf[i] * coefficient);
i+=1; fmoff     = buf[i] = (fmoff  * (1-coefficient)) + (buf[i] * coefficient);
i+=1; speed     = buf[i] = (speed  * (1-coefficient)) + (buf[i] * coefficient);

/*OSCILLATOR 1*/
adj1  = (twopi/srate*out2*fm1)+frequency+osc1f;
pos1 += adj1;
pos1 >= twopi ? pos1 -= twopi;
out1  = sin(pos1);

/*HP FILTER 1*/
otm1 = (hpcut)*otm1 + out1 - itm1; 
itm1 = out1;  
out1 = otm1;

/*FILTER*/
prefilter = out1;
buf0  = out1* (1-lpcut) + (buf0 * lpcut);
buf1  = buf0 * (1-lpcut) + (buf1 * lpcut);
buf2  = buf1 * (1-lpcut) + (buf2 * lpcut);
buf3  = buf2 * (1-lpcut) + (buf3 * lpcut);
buf4  = buf3 * (1-lpcut) + (buf4 * lpcut);
buf5  = buf4 * (1-lpcut) + (buf5 * lpcut);
buf6  = buf5 * (1-lpcut) + (buf6 * lpcut);
buf7  = buf6 * (1-lpcut) + (buf7 * lpcut);
buf8  = buf7 * (1-lpcut) + (buf8 * lpcut);
buf9  = buf8 * (1-lpcut) + (buf9 * lpcut);
buf10 = buf9 * (1-lpcut) + (buf10 * lpcut);
buf11 = buf10 * (1-lpcut) + (buf11 * lpcut);
buf12 = buf11 * (1-lpcut) + (buf12 * lpcut);
buf13 = buf12 * (1-lpcut) + (buf13 * lpcut);
buf14 = buf13 * (1-lpcut) + (buf14 * lpcut);
buf15 = buf14 * (1-lpcut) + (buf15 * lpcut);

taps == 0 ? out1 = buf0;
taps == 1 ? out1 = buf1;
taps == 2 ? out1 = buf3;
taps == 3 ? out1 = buf7;
taps == 4 ? out1 = buf15;
 
/*OSCILLATOR 2*/
adj2  = (twopi/srate*out1*fm2)+frequency+osc2f;
pos2 += adj2;
pos2 >= twopi ? pos2 -= twopi;
out2  = sin(pos2+pi/2);

/*HP FILTER 2*/
otm3 = (hpcut)*otm3 + out2 - itm3;
itm3 = out2; 
out2 = otm3;

/*MIX CONFIGURATIONS*/
mix == 0 ? (finalout1 = prefilter; finalout2 = out2);
mix == 1 ? (finalout1 = out1; finalout2 = out2);
mix == 2 ? finalout1 = finalout2 = prefilter;
mix == 3 ? finalout1 = finalout2 = out1;
mix == 4 ? finalout1 = finalout2 = out2;
mix == 5 ? finalout1 = finalout2 = (prefilter+out2)/2;
mix == 6 ? finalout1 = finalout2 = (out1+out2)/2;

/*VOLUME & PAN*/
finalout1 = finalout1*volume*(1-pan);
finalout2 = finalout2*volume*pan;

/*DC FILTERS*/
otm5      = .9999*otm5 + finalout1 - itm5; 
itm5      = finalout1; 
finalout1 = otm5;

otm6      = .9999*otm6 + finalout2 - itm6;
itm6      = finalout2;
finalout2 = otm6;

/*SPEAKER PROTECTION*/
finalout1 > 1 || finalout1 < -1 ? slider20=0;
finalout2 > 1 || finalout2 < -1 ? slider20=0;

/*LIMITER*/
finalout1 = clamp(finalout1,-1,1);
finalout2 = clamp(finalout2,-1,1);

/*OUTPUT*/
spl0 = finalout1;
spl1 = finalout2;
